﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using UpdaterForm.CustomTreeView;

namespace UpdaterForm
{
    public class Update : Observable
    {
        private readonly AppData _target;
        private bool _inProgress;
        private UpdateState _isInstalled;
        private UpdateLog _log;

        public Update(DirectoryInfo source, AppData target)
        {
            InProgress = false;
            _target = target;
            UpdateData = new UpdateData(source);
            UpdateFolder = new FolderNode(source, _target.InstallationPath);
            UpdateFolder.Name = UpdateData.DateName;
            UpdateFolder.Initialize();
            Content = UpdateFolder.Children;
            IsInstalled = UpdateData.DateName.Equals(target.CurrentVersion)
                ? UpdateState.CurrentVesion
                : target.History.GetStatus(UpdateData.DateName);
            Log = _target.History.GetLog(UpdateData.DateName);
        }

        public UpdateData UpdateData { get; set; }
        public Boolean Custom { get; set; }
        public ATreeNode UpdateFolder { get; set; }
        public List<ATreeNode> Content { get; set; }

        public UpdateLog Log
        {
            get { return _log; }
            set
            {
                _log = value;
                OnPropertyChanged("Log");
            }
        }

        public UpdateState IsInstalled
        {
            get { return _isInstalled; }
            set
            {
                _isInstalled = value;
                OnPropertyChanged("IsInstalled");
            }
        }

        public bool InProgress
        {
            get { return _inProgress; }
            set
            {
                _inProgress = value;
                OnPropertyChanged("InProgress");
            }
        }

        public void Install()
        {
            InProgress = true;
            if (Log == null)
            {
                //Esli loga netu to sozdadim ego i dobavim
                Log = new UpdateLog
                {
                    Name = UpdateData.DateName,
                    Time = DateTime.Now
                };
                _target.History.Logs.Add(Log);
            }

            UpdateState state;
            try
            {
                CheckForModifications();
                foreach (ATreeNode node in Content)
                    node.Apply(Custom);

                _target.CalculateSum();

                state = Custom
                    ? (Log.TransferedFiles.Count == UpdateData.Lenght
                        ? UpdateState.FullyInstalled
                        : UpdateState.PartlyInstalled)
                    : UpdateState.FullyInstalled;
                Log.FailReason = null;
            }
            catch (Exception e)
            {
                state = UpdateState.InstallFailed;
                Log.FailReason = e.Message;
            }

            Log.State = state;
            Log.Time = DateTime.Now;
            IsInstalled = state;

            OnPropertyChanged("Log");
            InProgress = false;
        }

        private void CheckForModifications()
        {
            if (!_target.ControllCheckSumm())
            {
                DialogResult res = MessageBox.Show("App source was changet from outside. Proceed?",
                    "Checksum control fail",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Error);
                if (res == DialogResult.No)
                {
                    throw new Exception("App source was changed from outside.");
                }
            }
        }
    }
}